import os
import pyttsx3
import comtypes.client
from pptx import Presentation
# from moviepy.editor import ImageClip, AudioFileClip, concatenate_videoclips
from moviepy import ImageClip, AudioFileClip, concatenate_videoclips


#从ppt提取文本
def extract_text_from_ppt(ppt_path):
    # 打开ppt文件
    prs = Presentation(ppt_path)
    # 创建一个空列表，用于存储每一页的文本
    slides_text = []
    # 遍历每一页
    for slide in prs.slides:
        # 创建一个空列表，用于存储当前页的文本
        slide_text = []
        # 遍历每一页中的每一个形状
        for shape in slide.shapes:
            # 如果形状有文本属性
            if hasattr(shape, "text"):
                # 将文本添加到当前页的文本列表中
                slide_text.append(shape.text)
        # 将当前页的文本列表转换为字符串，并添加到总文本列表中
        slides_text.append("\n".join(slide_text))
    # 返回总文本列表
    return slides_text


#文字转语音
def text_to_audio(text_list, output_folder):
    # 初始化语音引擎
    engine = pyttsx3.init()
    # 设置语速
    engine.setProperty('rate', 150)  # 调整语速
    # 设置音量
    engine.setProperty('volume', 0.7 )  # 调整音量
    # 设置语音
    engine.setProperty('voice', 'zh')  # 设置语音为中文
    # 创建一个空列表，用于存储生成的音频文件路径
    audio_files = []

    # 遍历文本列表
    for i, text in enumerate(text_list):
        # 生成音频文件路径
        audio_path = os.path.join(output_folder, f"slide_{i}.mp3")
        # 如果文本为空，朗读一个空格，生成一个极短音频作为占位
        if not text.strip():
            # 如果为空页，朗读一个空格，生成一个极短音频作为占位
            engine.save_to_file(" ", audio_path)
        else:
            engine.save_to_file(text, audio_path)
        audio_files.append(audio_path)
    engine.runAndWait()
    return audio_files


#PPT转图片
def ppt_to_images(ppt_path, image_folder):
    # 创建Powerpoint应用程序对象
    powerpoint = comtypes.client.CreateObject("Powerpoint.Application")
    # 设置Powerpoint应用程序可见
    powerpoint.Visible = 1
    # 打开指定的ppt文件
    deck = powerpoint.Presentations.Open(ppt_path)
    # 将ppt文件保存为图片，格式为jpeg
    deck.SaveAs(image_folder, 17)  # formatType = 17 for jpeg
    # 关闭ppt文件
    deck.Close()
    # 退出Powerpoint应用程序
    powerpoint.Quit()

    # 获取保存的图片文件列表
    #如果保存图片时是slide_0.jpg这种格式用这个
    # image_files = sorted(
    #     [os.path.join(image_folder, f) for f in os.listdir(image_folder) if f.endswith((".jpg",".JPG"))],
    #     key=lambda x: int(os.path.splitext(os.path.basename(x))[0].split("_")[-1])
    # )
    #如果保存图片时是slide1.jpg这种格式用这个
    image_files = sorted(
        [os.path.join(image_folder, f) for f in os.listdir(image_folder) if f.endswith((".jpg", ".JPG"))],
        key=lambda x: int(''.join(filter(str.isdigit, os.path.splitext(os.path.basename(x))[0])))
    )

    # 返回图片文件列表
    return image_files


#将图片和音频合成视频。每一页图片和音频对应
def create_video_from_images_and_audios(image_files, audio_files, output_video):
    # 创建一个空列表，用于存储视频片段
    clips = []
    # 遍历图片文件和音频文件
    for image_file, audio_file in zip(image_files, audio_files):
        # 从音频文件中创建音频片段
        audio_clip = AudioFileClip(audio_file)
        # 获取音频片段的时长
        duration = audio_clip.duration
        # 从图片文件中创建视频片段，并设置时长和音频
        clip = ImageClip(image_file).with_duration(duration).with_audio(audio_clip)
        # 将视频片段添加到列表中
        clips.append(clip)

    # 将所有视频片段连接起来，生成最终的视频片段
    final_clip = concatenate_videoclips(clips, method="compose")
    # 将最终的视频片段写入文件，设置帧率为24，视频编码为libx264，音频编码为aac
    final_clip.write_videofile(output_video, fps=24, codec="libx264", audio_codec="aac")


#主函数
def main(ppt_path, output_folder, output_video):
    # 创建输出文件夹
    os.makedirs(output_folder, exist_ok=True)
    # 创建输出图片文件夹
    os.makedirs(os.path.join(output_folder, "images"), exist_ok=True)

    # 提取讲稿文本
    print("1. 提取讲稿文本...")
    slides_text = extract_text_from_ppt(ppt_path)

    # 文字转语音
    print("2. 文字转语音...")
    audio_files = text_to_audio(slides_text, output_folder)

    # PPT转图片
    print("3. PPT转图片...")
    image_folder = os.path.join(output_folder, "images")
    image_files = ppt_to_images(ppt_path, image_folder)

    # 合成视频
    print("4. 合成视频...")
    create_video_from_images_and_audios(image_files, audio_files, output_video)

if __name__ == "__main__":
    ppt = r"C:\Users\hexq\PycharmProjects\mypy\video\qiheqixiangjv\qiqx.pptx"
    output_dir = r"C:\Users\hexq\PycharmProjects\mypy\video\qiheqixiangjv"
    output_video = os.path.join(output_dir, "presentation_video.mp4")

    main(ppt, output_dir, output_video)
